home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / editors / emacs / xemacs / xemacs-1.004 / xemacs-1 / xemacs-19.13 / src / signal.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-08-15  |  19.8 KB  |  708 lines

  1. /* Handling asynchronous signals.
  2.    Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
  3.    Copyright (C) 1995 Ben Wing.
  4.  
  5. This file is part of XEmacs.
  6.  
  7. XEmacs is free software; you can redistribute it and/or modify it
  8. under the terms of the GNU General Public License as published by the
  9. Free Software Foundation; either version 2, or (at your option) any
  10. later version.
  11.  
  12. XEmacs is distributed in the hope that it will be useful, but WITHOUT
  13. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15. for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with XEmacs; see the file COPYING.  If not, write to the Free
  19. Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21. /* Just to make sure we don't use any global vars below */
  22. #define DONT_DECLARE_MAC_VARS
  23.  
  24. #include <config.h>
  25. #include "lisp.h"
  26.  
  27. #include "device.h"
  28. #include "events.h" /* for signal_fake_event() */
  29. #include "frame.h"
  30. #include "sysdep.h"
  31. #include "syssignal.h"
  32. #include "systime.h"
  33.  
  34. #include <errno.h>
  35.  
  36. /* Set to 1 when a quit-check signal (either a SIGIO interrupt or
  37.    the asynch. timeout for poll-for-quit) occurs.  The QUITP
  38.    macro may look at this. */
  39. volatile int quit_check_signal_happened;
  40.  
  41. /* Count of the number of times a quit-check signal has occurred.
  42.    Some stuff in event-Xt.c looks at this. */
  43. volatile int quit_check_signal_tick_count;
  44.  
  45. /* Set to 1 when a SIGINT (or SIGQUIT) interrupt is processed.
  46.    maybe_read_quit_event() looks at this. */
  47. volatile int sigint_happened;
  48.  
  49. /* Set to 1 when an asynch. timeout signal occurs. */
  50. static volatile int alarm_happened;
  51.  
  52. /* This is used to synchronize setting the waiting_for_user_input_p
  53.    flag. */
  54. static volatile int alarm_happened_while_emacs_was_blocking;
  55.  
  56. #if !defined (SIGIO) && !defined (DONT_POLL_FOR_QUIT)
  57. int poll_for_quit_id;
  58. #endif
  59.  
  60. #ifndef SIGCHLD
  61. int poll_for_sigchld_id;
  62. #endif
  63.  
  64. /* This variable is used to communicate to a lisp
  65.    process-filter/sentinel/asynchronous callback (via the function
  66.    Fwaiting_for_user_input_p below) whether XEmacs was waiting for
  67.    user-input when that process-filter was called. */
  68. static int waiting_for_user_input_p;
  69.  
  70. static int interrupts_slowed_down;
  71.  
  72. #define SLOWED_DOWN_INTERRUPTS_SECS 5
  73. #define NORMAL_QUIT_CHECK_TIMEOUT_MSECS 250
  74. #define NORMAL_SIGCHLD_CHECK_TIMEOUT_MSECS 250
  75.  
  76. /* Used so that signals can break out of system calls that aren't
  77.    naturally interruptible. */
  78.  
  79. jmp_buf break_system_call_jump;
  80. int can_break_system_calls;
  81.  
  82.  
  83. /**********************************************************************/
  84. /*                  Asynchronous timeout functions                    */
  85. /**********************************************************************/
  86.  
  87. /* The pending timers are stored in an ordered list, where the first timer
  88.    on the list is the first one to fire.  Times recorded here are
  89.    absolute. */
  90. static struct low_level_timeout *async_timer_queue;
  91.  
  92. /* Nonzero means async timers are temporarily suppressed.  */
  93. static int async_timer_suppress_count;
  94.  
  95. static void
  96. set_one_shot_timer (EMACS_TIME interval)
  97. {
  98. #ifdef HAVE_SETITIMER
  99.   struct itimerval it;
  100.   it.it_value = interval;
  101.   EMACS_SET_SECS_USECS (it.it_interval, 0, 0);
  102.   setitimer (ITIMER_REAL, &it, 0);
  103. #else
  104.   int secs;
  105.   EMACS_TIME_TO_INT (interval, secs);
  106.   alarm (secs);
  107. #endif
  108. }
  109.  
  110. static void
  111. reset_interval_timer (void)
  112. {
  113.   EMACS_TIME interval;
  114.  
  115.   /* Get the interval to set.  If an interval is available,
  116.      make sure it's not zero (this is a valid return, but it will
  117.      cause the timer to get disabled, so convert it to a very short
  118.      time). */
  119.   if (get_low_level_timeout_interval (async_timer_queue, &interval))
  120.     {
  121.       if (EMACS_SECS (interval) == 0 && EMACS_USECS (interval) == 0)
  122.     EMACS_SET_USECS (interval, 1);
  123.     }
  124.   else
  125.     /* A time of 0 means "disable". */
  126.     EMACS_SET_SECS_USECS (interval, 0, 0);
  127.  
  128.   set_one_shot_timer (interval);
  129. }
  130.  
  131. int
  132. event_stream_add_async_timeout (EMACS_TIME time)
  133. {
  134.   int id = add_low_level_timeout (&async_timer_queue, time);
  135.  
  136.   /* If this timeout is at the head of the queue, then we need to
  137.      set the timer right now for this timeout.  Otherwise, things
  138.      are fine as-is; after the timers ahead of us are signalled,
  139.      the timer will be set for us. */
  140.  
  141.   if (async_timer_queue->id == id)
  142.     reset_interval_timer ();
  143.  
  144.   return id;
  145. }
  146.  
  147. void
  148. event_stream_remove_async_timeout (int id)
  149. {
  150.   int first = (async_timer_queue && async_timer_queue->id == id);
  151.   remove_low_level_timeout (&async_timer_queue, id);
  152.  
  153.   /* If we removed the timeout from the head of the queue, then
  154.      we need to reset the interval timer right now. */
  155.   if (first)
  156.     reset_interval_timer ();
  157. }
  158.  
  159. /* Handle an alarm once each second and read pending input
  160.    so as to handle a C-g if it comes in.  */
  161.  
  162. static SIGTYPE
  163. alarm_signal (int signo)
  164. {
  165.   if (interrupts_slowed_down)
  166.     {
  167.       something_happened = 1; /* tell QUIT to wake up */
  168.       /* we are in "slowed-down interrupts" mode; the only alarm
  169.      happening here is the slowed-down quit-check alarm, so
  170.      we set this flag.
  171.  
  172.      Do NOT set alarm_happened, because we don't want anyone
  173.      looking at the timeout queue.  We didn't set it and
  174.      it needs to stay the way it is. */
  175.       quit_check_signal_happened = 1;
  176.  
  177.       /* can_break_system_calls is set when we want to break out of
  178.      non-interruptible system calls. */
  179.       if (can_break_system_calls)
  180.     {
  181.       /* reset the flag for safety and such.  Do this *before*
  182.          unblocking or reestablishing the signal to avoid potential
  183.          race conditions. */
  184.       can_break_system_calls = 0;
  185.       EMACS_UNBLOCK_SIGNAL (signo);
  186.       EMACS_REESTABLISH_SIGNAL (signo, alarm_signal);
  187.       longjmp (break_system_call_jump, 0);
  188.     }
  189.  
  190.       EMACS_REESTABLISH_SIGNAL (signo, alarm_signal);
  191.       SIGRETURN;
  192.     }
  193.  
  194.   something_happened = 1; /* tell QUIT to wake up */
  195.   alarm_happened = 1;
  196.   if (emacs_is_blocking)
  197.     alarm_happened_while_emacs_was_blocking = 1;
  198.   /* #### This is for QUITP.  When it is run, it may not be the
  199.      place to do arbitrary stuff like run asynch. handlers, but
  200.      it needs to know whether the poll-for-quit asynch. timeout
  201.      went off.  Rather than put the code in to compute this
  202.      specially, we just set this flag.  Should fix this. */
  203.   quit_check_signal_happened = 1;
  204.   signal_fake_event ();
  205.  
  206.   EMACS_REESTABLISH_SIGNAL (signo, alarm_signal);
  207.   SIGRETURN;
  208. }
  209.  
  210. static void
  211. init_async_timeouts (void)
  212. {
  213.   signal (SIGALRM, alarm_signal);
  214.   async_timer_suppress_count = 0;
  215. }
  216.  
  217. /* Turn off async timeouts.  */
  218.  
  219. static void
  220. stop_async_timeouts (void)
  221. {
  222.   if (async_timer_suppress_count == 0)
  223.     {
  224.       /* If timer was on, turn it off. */
  225.       EMACS_TIME time;
  226.       EMACS_SET_SECS_USECS (time, 0, 0);
  227.       set_one_shot_timer (time);
  228.     }
  229.   async_timer_suppress_count++;
  230. }
  231.  
  232. /* Turn on async timeouts again. */
  233.  
  234. static void
  235. start_async_timeouts (void)
  236. {
  237.   assert (async_timer_suppress_count > 0);
  238.   async_timer_suppress_count--;
  239.   if (async_timer_suppress_count == 0)
  240.     {
  241.       /* Some callers turn off async timeouts and then use the alarm
  242.      for their own purposes; so reinitialize everything. */
  243.       signal (SIGALRM, alarm_signal);
  244.       reset_interval_timer ();
  245.     }
  246. }
  247.  
  248. /* Some functions don't like being interrupted with SIGALRM or SIGIO.
  249.    Previously we were calling stop_interrupts() / start_interrupts(),
  250.    but then if the program hangs in one of those functions, e.g.
  251.    waiting for a connect(), we're really screwed.  So instead we
  252.    just "slow them down".  We do this by disabling all interrupts
  253.    and then installing a timer of length fairly large, like 5 or
  254.    10 secs.  That way, any "legitimate" connections (which should
  255.    take a fairly short amount of time) go through OK, but we can
  256.    interrupt bogus ones. */
  257.  
  258. void
  259. slow_down_interrupts (void)
  260. {
  261.   EMACS_TIME time;
  262.  
  263.   /* We have to set the flag *before* setting the slowed-down timer,
  264.      to avoid a race condition -- if the signal occurs between the
  265.      call to set_one_shot_timer() and the setting of this flag,
  266.      alarm_happened will get set, which will be a Bad Thing if
  267.      there were no timeouts on the queue. */
  268.   interrupts_slowed_down++;
  269.   if (interrupts_slowed_down == 1)
  270.     {
  271.       stop_interrupts ();
  272.       EMACS_SET_SECS_USECS (time, SLOWED_DOWN_INTERRUPTS_SECS, 0);
  273.       set_one_shot_timer (time);
  274.     }
  275. }
  276.  
  277. void
  278. speed_up_interrupts (void)
  279. {
  280.   if (interrupts_slowed_down > 0)
  281.     {
  282.       start_interrupts ();
  283.       /* Change this flag AFTER fiddling with interrupts, for the same
  284.      race-condition reasons as above. */
  285.       interrupts_slowed_down--;
  286.     }
  287. }
  288.  
  289. static void
  290. handle_alarm_going_off (void)
  291. {
  292.   int interval_id;
  293.  
  294.   /* If asynch. timeouts are blocked, then don't do anything now,
  295.      but make this function get called again next QUIT.
  296.  
  297.      #### This is a bit inefficient because there will be function call
  298.      overhead each time QUIT occurs. */
  299.      
  300.   if (!NILP (Vinhibit_quit))
  301.     {
  302.       something_happened = 1;
  303.       alarm_happened = 1;
  304.       return;
  305.     }
  306.  
  307.   interval_id = pop_low_level_timeout (&async_timer_queue, 0);
  308.  
  309.   reset_interval_timer ();
  310.   if (alarm_happened_while_emacs_was_blocking)
  311.     {
  312.       alarm_happened_while_emacs_was_blocking = 0;
  313.       waiting_for_user_input_p = 1;
  314.     }
  315.   event_stream_deal_with_async_timeout (interval_id);
  316.   waiting_for_user_input_p = 0;
  317. }
  318.  
  319. #ifdef HAVE_SETITIMER
  320. unsigned int
  321. alarm (unsigned int howlong)
  322. {
  323.   struct itimerval old_it, new_it;
  324.  
  325.   /* If alarm() gets called when polling isn't disabled, it can mess
  326.      up the periodic timer. */
  327.   assert (async_timer_suppress_count > 0);
  328.  
  329.   new_it.it_value.tv_sec = howlong;
  330.   new_it.it_value.tv_usec = 0;
  331.   new_it.it_interval.tv_sec = 0;
  332.   new_it.it_interval.tv_usec = 0;
  333.   setitimer (ITIMER_REAL, &new_it, &old_it);
  334.  
  335.   /* Never return zero if there was a timer outstanding. */
  336.   return old_it.it_value.tv_sec + (old_it.it_value.tv_usec > 0 ? 1 : 0);
  337. }
  338. #endif
  339.  
  340. DEFUN ("waiting-for-user-input-p", Fwaiting_for_user_input_p,
  341.        Swaiting_for_user_input_p,
  342.        0, 0, 0,
  343.   "Return non-nil if XEmacs is waiting for input from the user.\n\
  344. This is intended for use by asynchronous timeout callbacks and by\n\
  345. asynchronous process output filters and sentinels (not yet implemented\n\
  346. in XEmacs).  It will always be nil if XEmacs is not inside of\n\
  347. an asynchronout timeout or process callback.")
  348.        ()
  349. {
  350.   return ((waiting_for_user_input_p) ? Qt : Qnil);
  351. }
  352.  
  353.  
  354. /**********************************************************************/
  355. /*                        Control-G checking                          */
  356. /**********************************************************************/
  357.  
  358. /* Set this for debugging, to have a way to get out */
  359. int stop_character; /* #### not currently implemented */
  360.  
  361. /* This routine is called in response to a SIGINT or SIGQUIT.
  362.    On TTY's, one of these two signals will get generated in response
  363.    to C-g.  (When running under X, C-g is handled using the SIGIO
  364.    handler, which sets a flag telling the QUIT macro to scan the
  365.    unread events for a ^G.)
  366.  
  367.    Otherwise it sets the Lisp variable  quit-flag  not-nil.
  368.    This causes  eval  to throw, when it gets a chance.
  369.    If  quit-flag  is already non-nil, it stops the job right away.  */
  370.  
  371. static SIGTYPE
  372. interrupt_signal (int sig)
  373. {
  374.   /* This function can GC (?!) */
  375.   /* Must preserve main program's value of errno.  */
  376.   int old_errno = errno;
  377.  
  378.   EMACS_REESTABLISH_SIGNAL (sig, interrupt_signal);
  379.  
  380. /* with the macroized error-checking stuff, the garbage below
  381.    may mess things up because XDEVICE() and such can use and
  382.    change global vars. */
  383. #if ! (defined (ERROR_CHECK_TYPECHECK) && defined (MACROIZE_ERROR_CHECKING))
  384.   if (sigint_happened && DEVICEP (Vcontrolling_terminal) &&
  385.       DEVICE_LIVE_P (XDEVICE (Vcontrolling_terminal)) &&
  386.       !emacs_is_blocking)
  387.     {
  388.       char c;
  389.       fflush (stdout);
  390.       reset_initial_device ();
  391.       EMACS_UNBLOCK_SIGNAL (sig);
  392. #ifdef SIGTSTP            /* Support possible in later USG versions */
  393. /*
  394.  * On systems which can suspend the current process and return to the original
  395.  * shell, this command causes the user to end up back at the shell.
  396.  * The "Auto-save" and "Abort" questions are not asked until
  397.  * the user elects to return to emacs, at which point he can save the current
  398.  * job and either dump core or continue.
  399.  */
  400.       sys_suspend ();
  401. #else
  402. #ifdef VMS
  403.       if (sys_suspend () == -1)
  404.     {
  405.       stdout_out ("Not running as a subprocess;\n");
  406.       stdout_out ("you can continue or abort.\n");
  407.     }
  408. #else /* not VMS */
  409.       /* Perhaps should really fork an inferior shell?
  410.      But that would not provide any way to get back
  411.      to the original shell, ever.  */
  412.       stdout_out ("No support for stopping a process on this operating system;\n");
  413.       stdout_out ("you can continue or abort.\n");
  414. #endif /* not VMS */
  415. #endif /* not SIGTSTP */
  416.       stdout_out ("Auto-save? (y or n) ");
  417.       fflush (stdout);
  418.       if (((c = getc (stdin)) & ~040) == 'Y')
  419.     Fdo_auto_save (Qnil, Qnil);
  420.       while (c != '\n')
  421.         c = getc (stdin);
  422. #ifdef VMS
  423.       stdout_out ("Abort (and enter debugger)? (y or n) ");
  424. #else /* not VMS */
  425.       stdout_out ("Abort (and dump core)? (y or n) ");
  426. #endif /* not VMS */
  427.       fflush (stdout);
  428.       if (((c = getc (stdin)) & ~040) == 'Y')
  429.     abort ();
  430.       while (c != '\n')
  431.         c = getc (stdin);
  432.       stdout_out ("Continuing...\n");
  433.       fflush (stdout);
  434.       reinit_initial_device ();
  435.       MARK_FRAME_CHANGED (XFRAME (DEVICE_SELECTED_FRAME
  436.                   (XDEVICE (Vcontrolling_terminal))));
  437.     }
  438.   else
  439. #endif /* ! (defined (ERROR_CHECKING) && defined (MACROIZE_ERROR_CHECKING)) */
  440.     {
  441.       /* Else request quit when it's safe */
  442.       Vquit_flag = Qt;
  443.       sigint_happened = 1;
  444.       signal_fake_event ();
  445.     }
  446.   errno = old_errno;
  447.   SIGRETURN;
  448. }
  449.  
  450. /* The effect of this function is to set Vquit_flag if the user pressed
  451.    ^G and discard the ^G, so as to not notice the same ^G again. */
  452. int 
  453. check_quit (void)
  454. {
  455.   if (quit_check_signal_happened)
  456.     {
  457.       quit_check_signal_happened = 0;
  458.       event_stream_quit_p ();
  459.       return 1;
  460.     }
  461.   else
  462.     return 0;
  463. }
  464.  
  465. int
  466. check_what_happened (void)        /* called from QUIT when
  467.                        something_happened gets set */
  468. {
  469.   something_happened = 0;
  470.   if (alarm_happened)
  471.     {
  472.       alarm_happened = 0;
  473.       handle_alarm_going_off ();
  474.     }
  475.   return check_quit ();
  476. }
  477.  
  478.   
  479. #if !defined (SIGIO) && !defined (DONT_POLL_FOR_QUIT)
  480.  
  481. static void
  482. init_poll_for_quit (void)
  483. {
  484.   /* Check for C-g every 1/4 of a second.
  485.  
  486.      #### This is just a guess.  Some investigation will have to be
  487.      done to see what the best value is.  The best value is the
  488.      smallest possible value that doesn't cause a significant amount
  489.      of running time to be spent in C-g checking. */
  490.   poll_for_quit_id =
  491.     event_stream_generate_wakeup (NORMAL_QUIT_CHECK_TIMEOUT_MSECS,
  492.                   NORMAL_QUIT_CHECK_TIMEOUT_MSECS,
  493.                   Qnil, Qnil, 1);
  494. }
  495.  
  496. #endif /* not SIGIO and not DONT_POLL_FOR_QUIT */
  497.  
  498. #ifndef SIGCHLD
  499.  
  500. static void
  501. init_poll_for_sigchld (void)
  502. {
  503.   /* Check for terminated processes every 1/4 of a second.
  504.  
  505.      #### This is just a guess.  Some investigation will have to be
  506.      done to see what the best value is.  The best value is the
  507.      smallest possible value that doesn't cause a significant amount
  508.      of running time to be spent in process-termination checking. */
  509.   poll_for_sigchld_id =
  510.     event_stream_generate_wakeup (NORMAL_SIGCHLD_CHECK_TIMEOUT_MSECS,
  511.                   NORMAL_SIGCHLD_CHECK_TIMEOUT_MSECS,
  512.                   Qnil, Qnil, 1);
  513. }
  514.  
  515. #endif /* not SIGCHLD */
  516.  
  517. #ifdef SIGIO
  518.  
  519. static void
  520. input_available_signal (int signo)
  521. {
  522.   something_happened = 1; /* tell QUIT to wake up */
  523.   quit_check_signal_happened = 1;
  524.   quit_check_signal_tick_count++;
  525.   EMACS_REESTABLISH_SIGNAL (signo, input_available_signal);
  526.   SIGRETURN;
  527. }
  528.  
  529. #endif /* SIGIO */
  530.  
  531.  
  532. /**********************************************************************/
  533. /*                     Enabling/disabling signals                     */
  534. /**********************************************************************/
  535.  
  536. static int interrupts_initted;
  537.  
  538. void
  539. stop_interrupts (void)
  540. {
  541.   if (!interrupts_initted)
  542.     return;
  543. #ifdef SIGIO
  544.   unrequest_sigio ();
  545. #endif
  546.   stop_async_timeouts ();
  547. }
  548.  
  549. void
  550. start_interrupts (void)
  551. {
  552.   if (!interrupts_initted)
  553.     return;
  554. #ifdef SIGIO
  555.   request_sigio ();
  556. #endif
  557.   start_async_timeouts ();
  558. }
  559.  
  560.  
  561. /************************************************************************/
  562. /*                            initialization                            */
  563. /************************************************************************/
  564.  
  565. void
  566. init_signals_very_early (void)
  567. {
  568.   /* Catch all signals that would kill us. */
  569.   if (! noninteractive || initialized)
  570.     {
  571.       /* Don't catch these signals in batch mode if not initialized.
  572.      On some machines, this sets static data that would make
  573.      signal fail to work right when the dumped Emacs is run.  */
  574.       signal (SIGHUP, fatal_error_signal);
  575.       signal (SIGQUIT, fatal_error_signal);
  576.       signal (SIGILL, fatal_error_signal);
  577.       signal (SIGTRAP, fatal_error_signal);
  578. #ifdef SIGABRT
  579.       signal (SIGABRT, fatal_error_signal);
  580. #endif
  581. #ifdef SIGHWE
  582.       signal (SIGHWE, fatal_error_signal);
  583. #endif
  584. #ifdef SIGPRE
  585.       signal (SIGPRE, fatal_error_signal);
  586. #endif
  587. #ifdef SIGORE
  588.       signal (SIGORE, fatal_error_signal);
  589. #endif
  590. #ifdef SIGUME
  591.       signal (SIGUME, fatal_error_signal);
  592. #endif
  593. #ifdef SIGDLK
  594.       signal (SIGDLK, fatal_error_signal);
  595. #endif
  596. #ifdef SIGCPULIM
  597.       signal (SIGCPULIM, fatal_error_signal);
  598. #endif
  599. #ifdef SIGIOT
  600.       signal (SIGIOT, fatal_error_signal);
  601. #endif
  602. #ifdef SIGEMT
  603.       signal (SIGEMT, fatal_error_signal);
  604. #endif
  605.       signal (SIGFPE, fatal_error_signal);
  606. #ifdef SIGBUS
  607.       signal (SIGBUS, fatal_error_signal);
  608. #endif
  609.       signal (SIGSEGV, fatal_error_signal);
  610. #ifdef SIGSYS
  611.       signal (SIGSYS, fatal_error_signal);
  612. #endif
  613.       signal (SIGPIPE, fatal_error_signal);
  614.       signal (SIGTERM, fatal_error_signal);
  615. #ifdef SIGXCPU
  616.       signal (SIGXCPU, fatal_error_signal);
  617. #endif
  618. #ifdef SIGXFSZ
  619.       signal (SIGXFSZ, fatal_error_signal);
  620. #endif /* SIGXFSZ */
  621.  
  622. #ifdef SIGDANGER
  623.       /* This just means available memory is getting low.  */
  624.       signal (SIGDANGER, memory_warning_signal);
  625. #endif
  626.  
  627. #ifdef SIGLOST
  628.       signal (SIGLOST, fatal_error_signal);
  629. #endif
  630. #ifdef SIGSTKFLT /* coprocessor stack fault under Linux */
  631.       signal (SIGSTKFLT, fatal_error_signal);
  632. #endif
  633. #ifdef SIGUSR1
  634.       signal (SIGUSR1, fatal_error_signal);
  635. #endif
  636. #ifdef SIGUSR2
  637.       signal (SIGUSR2, fatal_error_signal);
  638. #endif
  639. #ifdef SIGALRM
  640.       /* This will get reset later, once we're capable of handling
  641.      this properly. */
  642.       signal (SIGALRM, fatal_error_signal);
  643. #endif
  644. #ifdef SIGVTALRM
  645.       signal (SIGVTALRM, fatal_error_signal);
  646. #endif
  647. #ifdef SIGPROF
  648.       signal (SIGPROF, fatal_error_signal);
  649. #endif
  650. #ifdef SIGUNUSED /* exists under Linux, and will kill process! */
  651.       signal (SIGUNUSED, fatal_error_signal);
  652. #endif
  653.  
  654. #ifdef AIX
  655. /* 20 is SIGCHLD, 21 is SIGTTIN, 22 is SIGTTOU.  */
  656. #ifndef _I386
  657.       signal (SIGIOINT, fatal_error_signal);
  658. #endif
  659.       signal (SIGGRANT, fatal_error_signal);
  660.       signal (SIGRETRACT, fatal_error_signal);
  661.       signal (SIGSOUND, fatal_error_signal);
  662.       signal (SIGMSG, fatal_error_signal);
  663. #endif /* AIX */
  664.     }
  665. }
  666.  
  667. void
  668. syms_of_signal (void)
  669. {
  670.   defsubr (&Swaiting_for_user_input_p);
  671. }
  672.  
  673. void
  674. init_interrupts_late (void)
  675. {
  676.   if (!noninteractive)
  677.     {
  678.       signal (SIGINT, interrupt_signal);
  679. #ifdef HAVE_TERMIO
  680.       /* On  systems with TERMIO, C-g is set up for both SIGINT and SIGQUIT
  681.      and we can't tell which one it will give us.  */
  682.       signal (SIGQUIT, interrupt_signal);
  683. #endif /* HAVE_TERMIO */
  684.       init_async_timeouts ();
  685. #ifdef SIGIO
  686.       signal (SIGIO, input_available_signal);
  687. # ifdef SIGPOLL
  688.       /* Some systems (e.g. Motorola SVR4) losingly have different
  689.      values for SIGIO and SIGPOLL, and send SIGPOLL instead of
  690.      SIGIO.  On those same systems, an uncaught SIGPOLL kills the
  691.      process. */
  692.       signal (SIGPOLL, input_available_signal);
  693. # endif
  694. #elif !defined (DONT_POLL_FOR_QUIT)
  695.       init_poll_for_quit ();
  696. #endif
  697.     }
  698.  
  699. #ifndef SIGCHLD
  700.   init_poll_for_sigchld ();
  701. #endif
  702.  
  703.   EMACS_UNBLOCK_ALL_SIGNALS ();
  704.  
  705.   interrupts_initted = 1;
  706. }
  707.  
  708.